import tkinter as tk
from tkinter import ttk, messagebox
from ntplib import NTPClient
import datetime
import ctypes
import time

# 手动定义 SYSTEMTIME 结构体（兼容不同环境）
class SYSTEMTIME(ctypes.Structure):
    _fields_ = [
        ("wYear", ctypes.c_ushort),
        ("wMonth", ctypes.c_ushort),
        ("wDayOfWeek", ctypes.c_ushort),
        ("wDay", ctypes.c_ushort),
        ("wHour", ctypes.c_ushort),
        ("wMinute", ctypes.c_ushort),
        ("wSecond", ctypes.c_ushort),
        ("wMilliseconds", ctypes.c_ushort)
    ]

class NetworkTimeSyncApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("网络时间同步工具")
        self.geometry("400x400")
        self.resizable(False, False)
        
        # 设置界面
        self.setup_ui()
        
        # 初始化NTP客户端
        self.ntp_client = NTPClient()
        self.server = 'ntp.aliyun.com'  # 阿里时间服务器
        self.update_interval = 10       # 自动更新间隔（秒）
        
        # 开始自动更新时间显示
        self.update_time_display()
    
    def setup_ui(self):
        # 标题标签
        title_label = ttk.Label(self, text="网络时间同步工具", font=("Arial", 16, "bold"))
        title_label.pack(pady=15)
        
        # 时间显示框架
        time_frame = ttk.Frame(self)
        time_frame.pack(pady=10, fill=tk.X, padx=20)
        
        # 网络时间标签
        net_time_label = ttk.Label(time_frame, text="网络时间+0时区:", font=("Arial", 12))
        net_time_label.pack(anchor=tk.W)
        
        self.net_time_var = tk.StringVar(value="正在同步...")
        self.net_time_display = ttk.Label(time_frame, textvariable=self.net_time_var, 
                                         font=("Arial", 20), foreground="blue")
        self.net_time_display.pack(pady=5)
        
        # 本地时间标签
        local_time_label = ttk.Label(time_frame, text="本地时间:", font=("Arial", 12))
        local_time_label.pack(anchor=tk.W, pady=(10, 0))
        
        self.local_time_var = tk.StringVar(value="")
        self.local_time_display = ttk.Label(time_frame, textvariable=self.local_time_var, 
                                          font=("Arial", 20))
        self.local_time_display.pack(pady=5)
        
        # 状态标签
        self.status_var = tk.StringVar(value="状态: 未同步")
        status_label = ttk.Label(self, textvariable=self.status_var, foreground="red")
        status_label.pack(pady=10)
        
        # 同步按钮
        self.sync_button = ttk.Button(self, text="立即同步时间", command=self.sync_time)
        self.sync_button.pack(pady=10)
        
        # 自动同步选项
        self.auto_sync_var = tk.BooleanVar(value=True)
        auto_check = ttk.Checkbutton(self, text="自动同步(每10秒)", 
                                    variable=self.auto_sync_var, 
                                    command=self.toggle_auto_sync)
        auto_check.pack(pady=5)
    
    def update_time_display(self):
        if self.auto_sync_var.get():
            try:
                # 从阿里NTP服务器获取时间
                response = self.ntp_client.request(self.server, timeout=3)
                ntp_time = datetime.datetime.utcfromtimestamp(response.tx_time)
                self.net_time_var.set(ntp_time.strftime("%Y-%m-%d %H:%M:%S"))
                self.status_var.set(f"状态: 已同步({self.server})")
                
                # 更新本地时间显示（对比）
                local_time = datetime.datetime.now()
                self.local_time_var.set(local_time.strftime("%Y-%m-%d %H:%M:%S"))
            except Exception as e:
                self.net_time_var.set("同步失败")
                self.status_var.set(f"状态: 同步失败 - {str(e)}")
        
        # 每隔指定秒数更新一次显示
        self.after(self.update_interval * 1000, self.update_time_display)
    
    def sync_time(self):
        # 检查管理员权限（Windows需要）
        if not self.is_admin():
            messagebox.showerror("错误", "需要管理员权限才能修改系统时间！")
            self.status_var.set("状态: 同步失败 - 缺少管理员权限")
            return
        
        try:
            # 获取NTP服务器时间（UTC）
            response = self.ntp_client.request(self.server, timeout=5)
            ntp_time_utc = datetime.datetime.utcfromtimestamp(response.tx_time)
            
            # 转换为Windows需要的SYSTEMTIME结构体（UTC时间）
            system_time = SYSTEMTIME()
            system_time.wYear = ntp_time_utc.year
            system_time.wMonth = ntp_time_utc.month
            system_time.wDay = ntp_time_utc.day
            system_time.wHour = ntp_time_utc.hour
            system_time.wMinute = ntp_time_utc.minute
            system_time.wSecond = ntp_time_utc.second
            system_time.wMilliseconds = int(ntp_time_utc.microsecond / 1000)
            
            # 调用Windows API设置系统时间（UTC）
            ctypes.windll.kernel32.SetSystemTime(ctypes.byref(system_time))
            
            # 刷新本地时间显示
            local_time = datetime.datetime.now()
            self.net_time_var.set(ntp_time_utc.strftime("%Y-%m-%d %H:%M:%S"))
            self.local_time_var.set(local_time.strftime("%Y-%m-%d %H:%M:%S"))
            self.status_var.set(f"状态: 同步成功 ({self.server})")
            
            messagebox.showinfo("成功", "系统时间已同步为网络时间！")
        except Exception as e:
            self.status_var.set(f"状态: 同步失败 - {str(e)}")
            messagebox.showerror("错误", f"同步失败：{str(e)}")
    
    def toggle_auto_sync(self):
        # 切换自动同步状态
        self.update_interval = 10 if self.auto_sync_var.get() else 0
        self.status_var.set(f"状态: {'自动同步已开启' if self.auto_sync_var.get() else '自动同步已关闭'} ({self.server})")
    
    @staticmethod
    def is_admin():
        # 检查是否以管理员权限运行（Windows）
        try:
            return ctypes.windll.shell32.IsUserAnAdmin()
        except:
            return False

if __name__ == "__main__":
    app = NetworkTimeSyncApp()
    app.mainloop()
    #输出"感谢使用"
    print("感谢您使用该功能！")